package com.example.sql.manager.config;

import com.example.sql.manager.common.ResponseEntity;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

/**
 * 统一响应处理
 * ResponseBodyAdvice是Spring框架中的一个接口，可以用于在Controller的方法返回响应之前对响应进行统一处理。
 * 具体来说，它可用于对Controller方法返回的响应进行封装、格式化等操作，从而实现接口请求和响应的统一风格。
 * <p>
 * 实现ResponseBodyAdvice需要以下两个步骤：
 * 1、实现ResponseBodyAdvice接口，重写supports()和beforeBodyWrite()方法。
 * 其中，supports()方法用于判断当前请求是否支持该处理器，beforeBodyWrite()方法则用于在返回响应之前对响应进行统一处理。
 * 2、实现ResponseBodyAdvice接口，并通过@ControllerAdvice注解声明为全局处理器。
 * supports()方法判断Controller方法是否使用了@ResponseBody注解或返回类型是否为String，
 * 如果成立则表示当前请求支持该处理器；beforeBodyWrite()方法对响应进行统一处理
 * <p>
 */
@SuppressWarnings("NullableProblems")
@ControllerAdvice
public class ResponseBodyConfig implements ResponseBodyAdvice<Object> {


    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        // 判断Controller方法是否使用了@ResponseBody注解或返回类型是否为String
        return returnType.getMethodAnnotation(ResponseBody.class) != null || returnType.getParameterType().equals(String.class);
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType,
                                  MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType,
                                  ServerHttpRequest request, ServerHttpResponse response) {
        // 对响应进行统一处理
        if (body instanceof ResponseEntity) {
            return body;
        } else {
            return ResponseEntity.success(body);
        }

    }
}
